/*
 * The Open Source Unix Installer
 *
 * The MIT License
 *
 * Copyright 2011-2012 Andrey Pudov.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/*
 * @author  Andrey Pudov    <andrey@andreypudov.com>
 * @version 0.00.00
 * @name    u_xml_reader.h
 * @date:   Mar 18, 2012
 */

#ifndef INSTALLER_UTIL_XML_U_READER_H_
#define INSTALLER_UTIL_XML_U_READER_H_

#include <locale.h>     /* setlocale() */
#include <stdio.h>
#include <stdbool.h>

#include "xml_reader.h"

#include "u_main.h"

#ifdef __cplusplus
extern "C" {
#endif

bool u_installer_xml_reader_start();              /* unit entry point */

bool u_installer_xml_reader_new();
bool u_installer_xml_reader_delete();
bool u_installer_xml_reader_read();

bool u_installer_xml_reader_start() {
    return (u_installer_xml_reader_new()
        && u_installer_xml_reader_delete()
    	&& u_installer_xml_reader_read());
}

bool u_installer_xml_reader_new() {
    char file_name[] = "/tmp/installer-xml_reader_new";
    FILE *pointer    = fopen(file_name, "w");
    
    if (pointer == NULL) {
        fprintf(stderr, "[ERROR|%s] %s - %s\n",
                "u_installer_xml_reader_new", file_name, strerror(errno));
        return false;
    }
    
    XMLReader *reader = installer_xml_reader_new(pointer);
    if (reader == NULL) {
        u_installer_main_print("xml_reader", "new()", false);
    }
    
    installer_xml_reader_delete(reader);
    
    fclose(pointer);
    remove(file_name);
    
    u_installer_main_print("xml_reader", "new()", true);

    return true;
}

bool u_installer_xml_reader_delete() {
    /* unit case is a part of new() */        
    u_installer_main_print("xml_reader", "delete()", true);

    return true;
}

bool u_installer_xml_reader_read() {
    XMLReader    *reader    = NULL;
    XMLDocument  *document  = NULL;
    XMLElement   *element   = NULL;
    XMLElement   *element_t = NULL;
    XMLAttribute *attribute = NULL;
    
    wchar_t *element_name   = NULL;
    wchar_t *element_value  = NULL;
    
    setlocale(LC_ALL, "en_US.UTF-8");
    
    /* xml file content */
    const wchar_t *xml_unit = L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \
                               <!-- comment -->\n \
                               <parent>\n \
                                   <child1>Имя Имя Имя Имя</child1>\n \
                                   <child2>Name</child2>\n \
                                   <child3 />\n \
                               </parent>\n";

    /* creating the file */                       
    char file_name[] = "/tmp/installer-xml_reader_read";
    FILE *pointer    = fopen(file_name, "w+");
     
    if (pointer == NULL) {
        fprintf(stderr, "[ERROR|%s] %s - %s\n",
                "u_installer_xml_reader_read", file_name, strerror(errno));
        return false;
    }
    
    fwprintf(pointer, L"%ls\n", xml_unit);
    fclose(pointer);
    
    pointer = fopen(file_name, "r");
    if (pointer == NULL) {
        fprintf(stderr, "[ERROR|%s] %s - %s\n",
                "u_installer_xml_reader_read", file_name, strerror(errno));
        return false;
    }
    
    
    /* read the file and verifying the structure */
    reader   = installer_xml_reader_new(pointer);
    if (reader == NULL) {
        u_installer_main_print("xml_reader", "read(1)", false);
        return false;
    }
    
    document = installer_xml_reader_read(reader);
    if ((document == NULL) || (document->elements == NULL)) {
        u_installer_main_print("xml_reader", "read(2)", false);
        return false;
    }
    
    /* 
     * main unit-test code 
     */
     
    /* XML DOCUMENT v1.0 header */
    if (((element = installer_xml_document_get_element(document, NULL)) == NULL)
            || (wcscmp(installer_xml_element_get_name(element), L"XML DOCUMENT") != 0)
		    || (wcscmp(installer_xml_element_get_value(element), L"v1.0") != 0)) {
		    
	    element_name  = installer_xml_element_get_name(element);
	    element_value = installer_xml_element_get_value(element);

        u_installer_main_print("xml_reader", "read(3)", false);
        u_installer_main_trace("xml_reader", "read(3)", 
                               "\telement->name:    %ls\n" \
                               "\telement->value:   %ls\n",
                               element_name,
                               element_value);
        
        return false;
    }
    
    /* <?xml verion=\"1.0\" encoding=\"UTF-8\"?> */
    if (((element = installer_xml_document_get_element(document, NULL)) == NULL)
                || ((element = installer_xml_element_get_element(element, NULL)) == NULL)
            || (wcscmp(installer_xml_element_get_name(element), L"xml") != 0)
		    || (wcscmp(installer_xml_element_get_value(element), L"") != 0)
            || ((attribute = installer_xml_element_get_attribute(element, NULL)) == NULL)
                || (wcscmp(installer_xml_attribute_get_name(attribute), L"version") != 0)
                || (wcscmp(installer_xml_attribute_get_value(attribute), L"1.0") != 0)
            || ((attribute = installer_xml_element_get_attribute(element, attribute)) == NULL)
                || (wcscmp(installer_xml_attribute_get_name(attribute), L"encoding") != 0)
                || (wcscmp(installer_xml_attribute_get_value(attribute), L"UTF-8") != 0)) {
                
        element_name  = installer_xml_element_get_name(element);
	    element_value = installer_xml_element_get_value(element);
        
        u_installer_main_print("xml_reader", "read(4)", false);
        u_installer_main_trace("xml_reader", "read(4)", 
                               "\telement->name:    %ls\n" \
                               "\telement->value:   %ls\n",
                               element_name,
                               element_value);

        attribute = installer_xml_element_get_attribute(element, NULL);
        element_name  = installer_xml_attribute_get_name(attribute);
        element_value = installer_xml_attribute_get_value(attribute);
        if (attribute == NULL) {
            u_installer_main_trace("xml_reader", "read(4)", 
                                   "\tattribute(1):     NULL\n");
        }
        u_installer_main_trace("xml_reader", "read(4)", 
                               "\tattribute->name:  %ls\n" \
                               "\tattribute->value: %ls\n",
                               element_name,
                               element_value);

		attribute = installer_xml_element_get_attribute(element, attribute);
		element_name  = installer_xml_attribute_get_name(attribute);
        element_value = installer_xml_attribute_get_value(attribute);
        if (attribute == NULL) {
            u_installer_main_trace("xml_reader", "read(4)", 
                                   "\tattribute(2):     NULL\n");
        }
        u_installer_main_trace("xml_reader", "read(4)", 
                               "\tattribute->name:  %ls\n" \
                               "\tattribute->value: %ls\n",
                               element_name,
                               element_value);

        return false;
    }

    /* <parent> */
	if (((element = installer_xml_document_get_element(document, NULL)) == NULL)
            || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, element_t)) == NULL)
		|| (wcscmp(installer_xml_element_get_name(element_t), L"parent") != 0)
		|| (wcscmp(installer_xml_element_get_value(element_t), L"") != 0)) {
		
		element_name  = installer_xml_element_get_name(element_t);
	    element_value = installer_xml_element_get_value(element_t);

		u_installer_main_print("xml_reader", "read(5)", false);
		u_installer_main_trace("xml_reader", "read(5)", 
                               "\telement->name:    %ls\n" \
                               "\telement->value:   %ls\n",
                               element_name,
                               element_value);

		return false;
	}

	/* <child1>Имя Имя Имя Имя</child1> */
	if (((element = installer_xml_document_get_element(document, NULL)) == NULL)
            || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		    || ((element   = installer_xml_element_get_element(element, element_t)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		|| (wcscmp(installer_xml_element_get_name(element_t), L"child1") != 0)
		|| (wcscmp(installer_xml_element_get_value(element_t), L"Имя Имя Имя Имя") != 0)) {
		
		element_name  = installer_xml_element_get_name(element_t);
	    element_value = installer_xml_element_get_value(element_t);

		u_installer_main_print("xml_reader", "read(6)", false);
		u_installer_main_trace("xml_reader", "read(6)", 
                               "\telement->name:    %ls\n" \
                               "\telement->value:   %ls\n",
                               element_name,
                               element_value);

		return false;
	}

	/* <child2>Name</child2> */
	if (((element = installer_xml_document_get_element(document, NULL)) == NULL)
            || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		    || ((element   = installer_xml_element_get_element(element, element_t)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, element_t)) == NULL)
		|| (wcscmp(installer_xml_element_get_name(element_t), L"child2") != 0)
		|| (wcscmp(installer_xml_element_get_value(element_t), L"Name") != 0)) {
		
		element_name  = installer_xml_element_get_name(element_t);
	    element_value = installer_xml_element_get_value(element_t);

		u_installer_main_print("xml_reader", "read(7)", false);
		u_installer_main_trace("xml_reader", "read(7)", 
                               "\telement->name:    %ls\n" \
                               "\telement->value:   %ls\n",
                               element_name,
                               element_value);

		return false;
	}

	/* <child3 /> */
	if (((element = installer_xml_document_get_element(document, NULL)) == NULL)
            || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		    || ((element   = installer_xml_element_get_element(element, element_t)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, NULL)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, element_t)) == NULL)
		    || ((element_t = installer_xml_element_get_element(element, element_t)) == NULL)
		|| (wcscmp(installer_xml_element_get_name(element_t), L"child3") != 0)
		|| (wcscmp(installer_xml_element_get_value(element_t), L"") != 0)) {
		
		element_name  = installer_xml_element_get_name(element_t);
	    element_value = installer_xml_element_get_value(element_t);

		u_installer_main_print("xml_reader", "read(8)", false);
		u_installer_main_trace("xml_reader", "read(8)", 
                               "\telement->name:    %ls\n" \
                               "\telement->value:   %ls\n",
                               element_name,
                               element_value);

		return false;
	}
    
    installer_xml_reader_delete(reader);
    fclose(pointer);
    remove(file_name);
                           
    u_installer_main_print("xml_reader", "read()", true);

    return true;
}

#ifdef __cplusplus
}
#endif

#endif /* INSTALLER_UTIL_XML_U_READER_H_ */ 
